<?php
class User extends MY_Controller {

	// Modelos usados en las funciones del controlador
	var $modelUserDAO = 'User_dao';
	var $modelUserDTO = 'User_dto';
	
	var $modelRolDAO = 'Rol_dao';
	var $modelRolDTO = 'Rol_dto';
	
	// Vistas utilizadas en las funciones del controlador
	var $editionView = 'users/user_new_view';
	var $gridView = 'users/user_all_view';
	var $resultMessageView = '';
	var $emailView = 'users/user_email_view';
	
	// Datos para pasar a las vistas
	var $pageTitle = '';
	
	private $controllerName = 'user';
	
	public function __construct()
    {
    	parent::__construct();
		
		// Éstos modelos los cargo al inicio ya que los utilizo en la mayoría de los métodos
		$this->load->model("$this->modelUserDAO", 'User_dao');
		$this->load->model("$this->modelUserDTO", 'User_dto');
		
		$this->resultMessageView = $this->template->getResultMessageView();		
	}
	
	private function loadRolModels()
	{
		$this->load->model("$this->modelRolDAO", 'Rol_dao');
		$this->load->model("$this->modelRolDTO", 'Rol_dto');
	}
	
	public function getAll($result = '')
	{	
		// La acción sólo puede realizarla un administrador. Controlo los permisos antes de continuar
		if(parent::permitted($this->controllerName, 'getAll')) {
			$this->pageTitle = 'All Users';
			
			// Obtengo la lista de todos los usuarios del sistema
			$listaUsuarios = $this->User_dao->obtenerObjetos();
			
			// Defino cómo se van a mostrar los datos en la vista. Armo un arreglo con la consulta tal como es requerida
			$datosUsuarios = array();
			foreach($listaUsuarios as $usuario)
			{
				// Un usuario puede tener uno o más roles. A modo informativo, se concatenan todos los roles que tenga asociados
				// para mostrarlos. Por el momento se puede asociar únicamente UN SÓLO ROL al usuario
				$rolesUsuario = '';
				foreach($usuario->getRoles() as $rol) {
					$rolesUsuario .= (trim($rolesUsuario) == '' ? '' : ' / ') . $rol->getObjRol()->name;
				}
				
				$datosUsuarios[] = array('id'			=>	$usuario->id,
										 'firstName'	=>	$usuario->firstName,
										 'lastName'		=>	$usuario->lastName,
										 'email'		=>	$usuario->email,
										 'rol'			=>	$rolesUsuario,
										 'enabled'		=>	($usuario->deBaja ? 'No' : 'Yes'));
			}
			
			$dataView['usuarios'] = $datosUsuarios;

			if($result != '') $dataView['result'] = $result;
			
			parent::_loadViews($this->gridView, $dataView);
		}
		else { 
			parent::loadForbiddenView();
		}
	}
	
	public function editUser($idUser = 0)
	{
		$functionName = 'editUser';
		if($idUser == 0) { 
			$this->pageTitle = 'Add User';
			$functionName = 'adduser';
		}
		else { $this->pageTitle = 'Edit User'; }
		
		$this->loadEditionForm($idUser, $functionName);
	}
	
	private function loadEditionForm($idUsuario = 0, $function, $cargar_completa = FALSE, $isModal = TRUE)
	{
		// La acción sólo puede realizarla un administrador. Controlo los permisos antes de continuar
		if(parent::permitted($this->controllerName, $function)) {
			// Cargo las librerías y modelos que voy a utilizar
			$this->loadRolModels();
			
			// Para la carga de los usuarios, debo obtener los roles que pueden asociarse al mismo
			$rolesDeUsuarios = $this->Rol_dao->obtenerDatos();
			$dataView['roles'] = $rolesDeUsuarios;
	
			// Si se tratase de la edición de un usuario, éste se envió como parámetro. Lo envío en la información a la vista
			if ($idUsuario != 0) {
				// Obtengo el usuario que se desea modificar y mostrar en la vista
				$usuario = $this->User_dao->obtenerObjetoPorID($idUsuario);
				$dataView['usuario'] = $usuario;
			}
			
			$dataView['title'] = $this->pageTitle;
			$dataView['isModal'] = $isModal;

			if(!$cargar_completa) $this->load->view($this->editionView, $dataView);
			else parent::_loadViews($this->editionView, $dataView);
		}
		else { 
			parent::loadForbiddenView();
		}
	}
	
	public function saveUser()
	{	
		$this->pageTitle = 'Save user';		
	
		$id = is_numeric($this->input->post('idUsuario')) ? $this->input->post('idUsuario') : 0;

		//Se agregan las validaciones a los campos que corresponde
		$this->form_validation->set_rules('firstName','First Name','trim|required');
        $this->form_validation->set_rules('lastName','Last Name','trim|required');
        $this->form_validation->set_rules('email','Email','trim|required|valid_email|callback_validUsername');
		if($id == 0) $this->form_validation->set_rules('password','Password','trim|required|min_length[5]|max_length[9]');
		else $this->form_validation->set_rules('new_password','New Password','trim|min_length[5]|max_length[9]');
		$this->form_validation->set_rules('rol','Rol','required|is_natural');
		
        if ($this->form_validation->run() == FALSE)
        {
			// Alguno de los campos no pasó la validación anterior, vuelvo a mostrar el fomulario de edición	
			$this->loadEditionForm($id, ($id == 0 ? 'addUser' : 'editUser'), TRUE, FALSE);
        }else{ // La validación del formulario fue exitosa, puedo continuar y guardar los datos
			
			$changePassword = FALSE;
			
			// Obtengo los datos desde el formulario y los asigno al modelo
			if($id == 0) {
				$user = new User_dto();
				$user->id = 0;
			}
			else $user = $this->User_dao->obtenerObjetoPorID($id);
			
			$user->firstName = $this->input->post('firstName');
			$user->lastName = $this->input->post('lastName');
			$user->email = $this->input->post('email');
			$user->setUnicoRol($this->input->post('rol'));
			
			// El usuario que realizó los cambios sólo puede habilitar o inhabilitar a otros, no a sí mismo
			if($user->id != $_SESSION[$this->template->getIdUserSessionName()])
			{
				$user->deBaja = !$this->input->post('enabledUser');
			}
			
			$pass_ingresada = '';
			if ($user->id == 0) { // Usuario nuevo
				$changePassword = TRUE; // Para enviar el mail con cambio de clave
				$pass_ingresada = $this->input->post('password');
				$user->password = $pass_ingresada;
			}
			else { 
				$pass_ingresada = $this->input->post('new_password');
				$pass = $pass_ingresada;
				
				if(trim($pass) != '') { // Si está vacío el campo nueva pass significa que no debe cambiar
					// Encripto la pass obtenida
					$pass_encrip = $this->User_dao->encriptarDato($pass);

					if($pass_encrip != $user->password) {
						$user->password = $pass;
						
						// Si se cambia la clave del usuario, se le debe enviar un mail al usuario para notificarlo.
						// Se envía el mail sólo si el usuario no está dado de baja
						if(!$user->deBaja) { $changePassword = TRUE; }
					}
				}
			}

			$result = $this->User_dao->guardar($user);
			
			// Valido si ocurrió algún error al intentar guardar
			$errores = $result['error_msg'];
			$dataView['result'] = $errores;
			
			if($errores == '') {
				if($changePassword) {
					$errores = $this->_notifyNewPassword($user->firstName, $user->email, $pass_ingresada);	
				}
				
				redirect('user/getAll/' . $errores);
			}
			else parent::_loadViews("$this->resultMessageView", $dataView);
        }
	}
	
	function validUsername($usuario, $idUser = NULL)
	{
		if($idUser != NULL) $id = $idUser;
		else $id = is_numeric($this->input->post('idUsuario')) ? $this->input->post('idUsuario') : 0;

		if ($this->User_dao->existeNombreUsuario($usuario, $id)) {
			$this->form_validation->set_message('validUsername', 'This User name (Email) already exists.');
			return FALSE;
		}
		else {
			return TRUE;
		}
	}

	public function validUsernameJS()
	{
		$username = $this->input->post('mail');
		$id = $this->input->post('id');
		
		if(!$username) echo FALSE;
        else {
                $valido = $this->validUsername($username, $id);
                if ($valido) echo TRUE;
                else echo FALSE;
        }
	}
	
	private function _deleteUser($idUser)
	{
		// La acción sólo puede realizarla un administrador. Controlo los permisos antes de continuar
		if(parent::permitted($this->onlyAdmin)) {
			$this->pageTitle = 'Delete user';
			
			$result = $this->User_dao->borrar($idUser);
				
			// Valido si ocurrió algún error al intentar borrar
			$errores = $result['error_msg'];
			$dataView['result'] = $errores;
			
			if($errores == '') redirect('user/getAll');
			else parent::_loadViews("$this->resultMessageView", $dataView);
		}
		else { 
			parent::loadForbiddenView();
		}
	}
	
	private function _notifyNewPassword($firstname, $email, $password)
	{
		$message = '<td width="26">&nbsp;</td>
					<td valign="top" style="vertical-align:top;">
						<b>Dear ' . $firstname . ':</b>
					</td>
					<td>
						<br/>Your new password to access Reporting AZO is <b>' . $password . '</b>
					</td>';
		$errores = $this->_sendMail($message, 'Reporting AZO pass', $email);
		return $errores;
	}
	
	private function _mailEveryone($isModal = TRUE)
	{
		// La acción sólo puede realizarla un administrador. Controlo los permisos antes de continuar
		if(parent::permitted($this->controllerName, 'mailEveryone')) {
			$this->pageTitle = 'E-mail Everyone';

			$dataView['isModal'] = $isModal;
			parent::_loadViews("$this->emailView", $dataView);
		}
		else { 
			parent::loadForbiddenView();
		}
	}
	
	public function sendMailEveryone()
	{
		$this->pageTitle = 'E-mail everyone';
	
		// Se agregan las validaciones a los campos que corresponde
		$this->form_validation->set_rules('message','Message','trim|required|min_length[15]');
		
        if ($this->form_validation->run() == FALSE)
        {
			// Alguno de los campos no pasó la validación anterior, vuelvo a mostrar el fomulario de envío de mail
			$this->_mailEveryone(FALSE);
        }else{ // La validación del formulario fue exitosa, puedo continuar y enviar el mail
			
			$message = $this->input->post('message');
			$message = '<td width="26">&nbsp;</td>
						<td valign="top" style="vertical-align:top;">
							<b>Everyone:</b>
						</td>
						<td>
							<br/>' . $message .
						'</td>';
			
			// Valido si ocurrió algún error al intentar guardar
			$errores = $this->_sendMail($message, 'Reporting AZO News');
			
			if($errores === '') { 
				$result = "success";
				redirect('user/getAll/' . $result);
			}
			else { 
				$dataView['result'] = $errores;
				parent::_loadViews("$this->resultMessageView", $dataView);
			}
        }
	}
	
	
	private function _sendMail($message, $subject, $mailsTo = '')
	{
		$errores = '';
		
		// Obtengo la lista de mails de todos los usuarios para notificarlos de la nueva ronda
		if($mailsTo != '') $mails = $mailsTo;
		else $mails = $this->User_dao->obtenerMails();
		
		if($mails != '')
		{
			// Obtengo el mail del usuario actual del sistema
			if(isset($_SESSION[$this->template->getEmailSessionName()])) {
				$mailDesde = $_SESSION[$this->template->getEmailSessionName()];
				$userName = $_SESSION[$this->template->getUsernameSessionName()];
				
				$errores = parent::sendMail($mails, $userName, $mailDesde, $subject, $message);
			}
		}
		
		return $errores;
	}

	function prueba()
	{
		$this->load->library('encriptar');
		$dataView['user1'] = $this->encriptar->encrypt('lucasnanu', 'Lk12398sdF8s6ga0sdjlk2I09');


		parent::_loadViews('users/prueba', $dataView);
	}
}